package com.intel.factorytest.activity;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StatFs;
import android.os.SystemProperties;
import android.os.storage.StorageManager;
import android.os.storage.StorageEventListener;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;

import com.intel.factorytest.R;
import com.intel.factorytest.activity.SensorsTestActivity.ItemInfo;
import com.intel.factorytest.adapter.GridAdapter;
import com.intel.factorytest.application.MATApplication;
import com.intel.factorytest.cfparser.ConfigFileParseUtil;
import com.intel.factorytest.cfparser.concrete.AConfigFileParser;
import com.intel.factorytest.cfparser.concrete.PropertiesConfParser;
import com.intel.factorytest.log.LogWriter;
import com.intel.factorytest.util.SDCardUtil;
import com.intel.factorytest.util.Util;
import android.graphics.Color;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import android.text.TextUtils;
import android.text.format.Formatter;
import android.text.format.Formatter.BytesResult;

import android.os.storage.DiskInfo;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;



/**
 * 综合测试目前包括：电池状态，内外部存储器，USB，OTG
 */
public class SDCardTest extends BaseActivity {

    private static final String TEST_CASE_NAME = "SDCardTest";
    private static final String TAG = "SDCardTest";


    private boolean doSdCardReadTest = false;


    private boolean resultBatteryOK = false;
    private boolean resultSDCardOK = false;
    private boolean resultUsbOK = false;
    private boolean resultOtgOK = false;
    private boolean resultRFCalibOK = false;

    private boolean resultCharging = false;

    private String confValue;
    // testcase name
    private static final String TC_SdCard = "Internal/External memory";



    // index

    private static final int INDEX_SdCard = 1;


    // sdcard RAMCapability
    private static final String PATH_EMMC_CAPACITY = "/sys/class/block/mmcblk0/size";
    private static final String KEY_RAMCapability = "RAMCapability";
    private static final String KEY_ROMCapability = "ROMCapability";
    private static final String KEY_InternalStorageCardCapbility = "InternalStorageCardCapability";
    private static final String KEY_ExternalStorageCardCapbility = "ExternalStorageCardCapability";
    private static final String KEY_RAM_ERROR_LIMITATION = "RAM_ERROR_LIMITATION";
    private static final String KEY_ROM_ERROR_LIMITATION = "ROM_ERROR_LIMITATION";
    private static final String KEY_STORAGE_CARD_ERROR_LIMITATION = "STORAGE_CARD_ERROR_LIMITATION";

    private float[] internalStorageMemInfos = new float[] { 0, 0 };
    private float[] externalStorageMemInfos = new float[] { 0, 0 };
    private float[] tempStorageMemInfos = new float[] { 0, 0 };
    private boolean internalStorageCardOK = false;
    private boolean externalStorageCardOK = false;

    private Properties properties;
    private float valueRamCapability = 1; // unit: G
    private float valueRomCapability = 0; // unit: G
    private float valueInternalStorageCardCapability = 0; // unit: G
    private float valueExternalStorageCardCapability = 0; // unit: G
    private float valueRamSizeErrorLimitation = 0.2f; // unit: G
    private float valueRomSizeErrorLimitation = 0.2f; // unit: G
    private float valueSdCardSizeErrorLimitation = 0.2f; // unit: G

    TextView mTextView_SdCard;
    private float mTotalSize = 0;
    private float mAvailSize = 0;
    private float mMemoryTotalSize = 0;
    private float mMemoryAvailSize = 0;
    private float mRamTotalSize = 0;
    private float mRamFreeSize = 0;
    private float mRamUsedSize = 0;
    private float mRomTotalSize = 0;
    private float mRomAvailSize = 0;
    private String mProduct;
    private String mSdPath = "";
    private static final String TEST_RESULT = "test_result";
    private String mTextString_Sdcard = "";
    private static final int FRESH = 1;

    private String sTotalMemorySize = "0 MB";
    private String sTotalNandFlashSize = "0 GB";
    private String sTotalSDCardhSize = "0 GB";



    // Handler Message
    private static final int MSG_CHECK_RESULT = 1;

    private StorageManager mStorageManager;
    TextView sdcardText;
    TextView sdcardStatus;
    TextView sdcardValue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        properties = ((PropertiesConfParser) ConfigFileParseUtil
                .getConfParserConcrete(this,
                        AConfigFileParser.EXTENSION_PROPERTISE))
                .getProperties(isPcba);
        // get sdcard's configurations
        valueRamCapability = Float.parseFloat(properties.getProperty(
                KEY_RAMCapability, String.valueOf(valueRamCapability)));
        valueRomCapability = Float.parseFloat(properties.getProperty(
                KEY_ROMCapability, String.valueOf(valueRomCapability)));
        valueInternalStorageCardCapability = Float.parseFloat(properties
                .getProperty(KEY_InternalStorageCardCapbility,
                        String.valueOf(valueInternalStorageCardCapability)));
        valueExternalStorageCardCapability = Float.parseFloat(properties
                .getProperty(KEY_ExternalStorageCardCapbility,
                        String.valueOf(valueExternalStorageCardCapability)));
        valueRamSizeErrorLimitation = Float.parseFloat(properties.getProperty(
                KEY_RAM_ERROR_LIMITATION,
                String.valueOf(valueRamSizeErrorLimitation)));
        valueRomSizeErrorLimitation = Float.parseFloat(properties.getProperty(
                KEY_ROM_ERROR_LIMITATION,
                String.valueOf(valueRomSizeErrorLimitation)));
        valueSdCardSizeErrorLimitation = Float.parseFloat(properties
                .getProperty(KEY_STORAGE_CARD_ERROR_LIMITATION,
                        String.valueOf(valueSdCardSizeErrorLimitation)));
        setContentView(R.layout.sdcard_test);
        initView();
        if (isSystemTest) {
            Intent intent = getIntent();
            confValue = intent.getStringExtra("value");
            initTestByConfig(confValue);
        } else {
            doSdCardReadTest = true;
        }
        resultSDCardOK = false;
        initStorageList();
        Log.e(TAG, "ExternalStorageDirectory:" + Environment.getExternalStorageDirectory());
        Log.e(TAG, "ExternalStorageState:" + Environment.getExternalStorageState());
        mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);

        sTotalMemorySize = getTotalMemory();
        Log.d(TAG, "TotalMemorySize:" + sTotalMemorySize);

        sTotalNandFlashSize = getRomTotalsize();//getTotalNand();
        Log.d(TAG, "TotalNandFlashSize:" + sTotalNandFlashSize);

        //TestExternStorage(ExistSDCard(), true);
        refresh();
    }

    @Override
    protected void initView() {
        super.initView();
       // mSucBtn.requestFocus();//add by wangsm
        mSucBtn.setVisibility(View.INVISIBLE);//add by wangsm
        sdcardText = (TextView)findViewById(R.id.sdcard_text);
        sdcardStatus = (TextView)findViewById(R.id.sdcard_status);
        sdcardValue = (TextView)findViewById(R.id.sdcard_value);
    }



    private void initTestByConfig(String config) {
        if (config == null || config.trim().length() == 0)
            return;

        Log.i("tangjun comprehensive test", "config = " + config);

        String[] configs = config.split(";");
        for (String conf : configs) {
            String[] items = conf.split("=");

            // overall sensors' switch
            if (items.length == 1) {
                if (items[0].equals("0")) {
                    // Don't test any Sensor!
                    break;
                }
                continue;
            }

            // single sensor's switch
            boolean doTest = false;
            if (items[1].equals("1")) {
                doTest = true;
            }

             if (items[0].equals(TC_SdCard)) {
                doSdCardReadTest = doTest;
            }


        }
    }

    @Override
    protected void onResume() {
        super.onResume();


        // MicroSD
        // register BroadcastReceiver for MicroSD
        if (doSdCardReadTest) {
            IntentFilter intentFilterSD = new IntentFilter();
            intentFilterSD.addAction(Intent.ACTION_MEDIA_MOUNTED);
            intentFilterSD.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
            intentFilterSD.addAction(Intent.ACTION_MEDIA_EJECT);
            intentFilterSD.addDataScheme("file");
            registerReceiver(mReceiverPlugSdcard, intentFilterSD, "permission.CIT_ALLOW_BROADCAST", null);
        }
        mItemTestFinish = true;//add by wangsm
    }




    protected void onPause() {
        super.onPause();
        if (doSdCardReadTest) {
            unregisterReceiver(mReceiverPlugSdcard);
        }

    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }



    // #######################################################
    // # MicroSD #
    // #######################################################

    final BroadcastReceiver mReceiverPlugSdcard = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {

            Log.d(TAG, "enter onReceive " + intent.getAction());
            // Log.d(TAG, "getDataString: " + intent.getDataString());

            if (intent.getDataString().contains("sdcard1")) {
                if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED)) {
                    ExistSDCard();
                    TestExternStorage(true, false);
                } else {
                    TestExternStorage(false, false);
                }
            }

        }
    };

    private String internalStoragePath = "";
    private String externalStoragePath = "";
    private String[] storageList;

    private void initStorageList() {
        storageList = SDCardUtil.getStorageList(this);
        if (storageList != null) {
            for (String storageDir : storageList) {
                if (storageDir.contains("emulated")) {
                    internalStoragePath = storageDir;
                } else if (storageDir.contains("sdcard1")) {
                    externalStoragePath = storageDir;
                } else {
                    // do nothing
                }
            }
        }
    }







    @Override
    public void finish() {
        super.finish();
    }

    private boolean isAllTestOK() {
        boolean storageCardOK = false;


        if (doSdCardReadTest) {
            if (resultSDCardOK) {
                storageCardOK = true;
            }
        } else {
            storageCardOK = true;
        }

        return storageCardOK;
    }


    private String getTotalMemory() {
        String str1 = "/proc/meminfo";// 系统内存信息文件
        String str2;
        String[] arrayOfString;
        long initial_memory = 0;

        try {
            FileReader localFileReader = new FileReader(str1);
            BufferedReader localBufferedReader = new BufferedReader(
                    localFileReader, 8192);
            str2 = localBufferedReader.readLine();// 读取meminfo第一行，系统总内存大小

            arrayOfString = str2.split("\\s+");
            for (String num : arrayOfString) {
                Log.i(str2, num + "\t");
            }

            initial_memory = Integer.valueOf(arrayOfString[1]).intValue() * 1024;// 获得系统总内存，单位是KB，乘以1024转换为Byte
            Log.d(TAG, "getTotalMemory initial_memory " + initial_memory);

            localBufferedReader.close();

        } catch (IOException e) {
        }
        return Formatter.formatFileSize(getBaseContext(), -initial_memory);// Byte转换为KB或者MB，内存大小规格化
    }

    private String getTotalNand() {
        long size = 0;
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(
                    "/sys/class/block/mmcblk0/size"));
            String sizeStr = "";
            if (null != (sizeStr = br.readLine())) {
                size = Integer.parseInt(sizeStr);
                // size = size / 2 / 1024 / 1024;
                size = size * 512;
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NumberFormatException e) {
            // TODO: handle exception
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        return Formatter.formatFileSize(getBaseContext(), size);
    }

    private String getRomTotalsize(){
                final StatFs stat = new StatFs(Environment.getDataDirectory().getPath());

                final float blockSize = stat.getBlockSize();
                final float totalBlocks = stat.getBlockCount();
                float totalSize = blockSize*totalBlocks;
                return Formatter.formatFileSize(getBaseContext(),((long)totalSize));
    }

    private long getTotalSize(String path) {
        synchronized (this) {
            Log.d(TAG, "path:" + path);
            try {
                StatFs statFs = null;
                File file = new File(path);
                if(false) {//user version fail!!!
                    File sdDir = new File("/dev/block/mmcblk1");
                    if (!sdDir.exists()) {
                      Log.d(TAG, "sdcard not insert");
                      return 0;
                    }
                } else {
                    boolean ismounted = Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED);
                    Log.e(TAG, "getTotalSize >>>> ismounted:" + ismounted);
                    if(!isSdcardMounted())
                        return 0;
                }
                if (file.exists()) {
                    statFs = new StatFs(path);

                    long blockSize = statFs.getBlockSize();
                    long totalBlocks = statFs.getBlockCount();
                    Log.d(TAG, "blockSize="+blockSize+",totalBlocks="+totalBlocks);
                    return blockSize * totalBlocks;
                } else {
                    Log.d(TAG, "file.exists()");
                    return 0;
                }
            } catch (Exception e) {
                Log.e(TAG, "Exception" + e.getMessage());
                return 0;
            }
        }

    }

    //get SD states,CHY
    private boolean isSdcardMounted(){
        boolean mounted = false;
        String line = null;
        BufferedReader reader = null;
        try{
            reader = new BufferedReader(new FileReader("/proc/mounts"));
            if(reader == null){
                Log.e(TAG, "isSdcardMounted >>> reader is NULL!!!");
                return mounted;
            }
            while ((line = reader.readLine()) != null) {
                String[] tmp = line.split(" ");
                if(tmp.length >= 2){
                    if(tmp[1] != null&& tmp[1].equals("/storage/sdcard1")){
                        mounted = true;
                        break;
                    }
                    Log.e(TAG, "isSdcardMounted >>> tmp:" + tmp[1]);
                }
            }
        }catch(FileNotFoundException e){
        }catch(IOException ee){
        }finally{
            try{
                if(reader != null)
                    reader.close();
            }catch(IOException eee){
            }
        }
        Log.d(TAG,"isSdcardMounted mounted:"+mounted);
        return mounted;
    }

    private void TestExternStorage(boolean bSDCard, boolean bSetBGRed) {

        mTextString_Sdcard = getString(R.string.SERVICEMENU_RAM_TOTALSIZE_TXT)
                + sTotalMemorySize + "\n";
        mTextString_Sdcard += getString(R.string.SERVICEMENU_ROM_TOTALSIZE_TXT)
                + sTotalNandFlashSize;// + "\n" //remove by wangsm

        if (bSDCard) {
            sdcardStatus.setText(R.string.SERVICEMENU_SDCARD_TOTALSIZE_TXT);
            sdcardValue.setText(sTotalSDCardhSize);
           /* mTextString_Sdcard += getString(R.string.SERVICEMENU_SDCARD_TOTALSIZE_TXT)
                    + sTotalSDCardhSize;*/
            resultSDCardOK = true;
            mSucBtn.setVisibility(View.VISIBLE);//add by wangsm
        } else {
            if (bSetBGRed) {
                resultSDCardOK = false;
            }
            sdcardStatus.setText(R.string.external_sdcard_status);
            sdcardValue.setTextColor(Color.RED);
            sdcardValue.setText(R.string.external_sdcard_not_insert);
           // mTextString_Sdcard += getString(R.string.SERVICEMENU_SDCARD_UNAVAILABLE_TXT);
        }
        sdcardText.setText(mTextString_Sdcard);

    }

    private boolean ExistSDCard() {
        String[] storagePathList = mStorageManager.getVolumePaths();
        if (storagePathList[1] != null) return true;
        return false;
    }

    private void refresh()
    {
        final List<VolumeInfo> volumes = mStorageManager.getVolumes();
        Collections.sort(volumes, VolumeInfo.getDescriptionComparator());
        boolean hasSDcard = false;
        String info = " ";
        for (VolumeInfo vol : volumes) {
            if (vol.getType() == VolumeInfo.TYPE_PUBLIC) {
                //Disable preference when in change
                if (vol.getState()!= VolumeInfo.STATE_CHECKING &&
                    vol.getState() != VolumeInfo.STATE_EJECTING) {
                    info += mStorageManager.getBestVolumeDescription(vol) + "\n";
                    if (vol.isMountedReadable()) {
                        // TODO: move statfs() to background thread
                        final File path = vol.getPath();
                        final long totalBytes = path.getTotalSpace();

                        final long freeBytes = path.getFreeSpace();
                        final long usedBytes = totalBytes - freeBytes;

                        final String used = Formatter.formatFileSize(this, usedBytes);
                        final String total = Formatter.formatFileSize(this, totalBytes);

                        info += total + "\n";
                    } else {
                        info += vol.getStateDescription() + "\n";
                    }

                    if(!hasSDcard) {
                        hasSDcard = true;
                    }

                }
            }
        }
        Log.d(TAG, "refresh info = " + info);

        if(!hasSDcard) {
            sdcardStatus.setText(R.string.external_sdcard_status);
            sdcardValue.setTextColor(Color.RED);
            sdcardValue.setText(R.string.external_sdcard_not_insert);
        } else {
            sdcardStatus.setText(R.string.SERVICEMENU_SDCARD_AVAILABLE_TXT);
            sdcardValue.setText(info);
            resultSDCardOK = true;
            mSucBtn.setVisibility(View.VISIBLE);//add by wangsm
        }

        //ROM
        mTextString_Sdcard = getString(R.string.SERVICEMENU_RAM_TOTALSIZE_TXT)
                + sTotalMemorySize + "\n";
        mTextString_Sdcard += getString(R.string.SERVICEMENU_ROM_TOTALSIZE_TXT)
                + sTotalNandFlashSize;
        sdcardText.setText(mTextString_Sdcard);
    }

}
